/**
 * Copyright (C) 2012 Oleg Anastassov <o.anastasov@gmail.com>
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package kz.kstu.ent.desktop.chart.graph;

import kz.kstu.ent.desktop.chart.Chart;
import kz.kstu.ent.desktop.chart.info.ChartInfo;
import kz.kstu.ent.desktop.common.ChartUtil;
import kz.kstu.ent.util.ColorUtil;
import kz.kstu.ent.util.DateUtil;
import kz.kstu.ent.util.NumberUtil;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.DateTickMarkPosition;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.StandardXYItemLabelGenerator;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.TimeSeriesCollection;

import java.awt.*;
import java.text.SimpleDateFormat;

/**
 * Date: 23.09.12
 * Time: 13:42
 *
 * @author Oleg Anastassov
 */
public abstract class Graph extends Chart {

    private TimeSeriesCollection dataset;

    protected Graph(ChartInfo info, TimeSeriesCollection dataset) {
        super(info);
        this.dataset = dataset;
    }

    public TimeSeriesCollection getDataset() {
        return dataset;
    }

    public void setDataset(TimeSeriesCollection dataset) {
        this.dataset = dataset;
    }

    private JFreeChart setDefaults(JFreeChart chart) {
        chart.setBackgroundPaint(ColorUtil.BACKGROUND_COLOR);

        final XYPlot plot = chart.getXYPlot();
        plot.setBackgroundPaint(Color.WHITE);
        plot.setDomainGridlinesVisible(true);
        plot.setDomainGridlinePaint(Color.lightGray);
        plot.setRangeGridlinesVisible(true);
        plot.setRangeGridlinePaint(Color.lightGray);
        plot.setDomainCrosshairVisible(true);
        plot.setRangeCrosshairVisible(false);

        // empty dataset message settings
        plot.setNoDataMessage(NO_DATA_MESSAGE);
        plot.setNoDataMessagePaint(Color.BLACK);

        // hide dates
        ValueAxis axis = plot.getDomainAxis();
        axis.setTickLabelsVisible(false);

        final XYItemRenderer xyItemRenderer = plot.getRenderer();
        if (xyItemRenderer instanceof XYLineAndShapeRenderer) {
            final XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) xyItemRenderer;
            renderer.setBaseShapesFilled(true);
            renderer.setBaseShapesVisible(true);
            renderer.setShapesVisible(true);
            renderer.setDrawOutlines(true);

            renderer.setBaseItemLabelGenerator(
                    new StandardXYItemLabelGenerator("{2}", NumberUtil.DECIMAL_FORMAT, NumberUtil.DECIMAL_FORMAT)
            );
            renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition());
            renderer.setBaseItemLabelsVisible(true);

            //sets the joint level size means the dot size which join two points on a graph 2f,3f
            Stroke stroke = new BasicStroke(3f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);
            renderer.setBaseOutlineStroke(stroke);
        }

        final DateAxis xAxis = (DateAxis) plot.getDomainAxis();
        //Change domain axis lable by 180/4=45 degree
        //axis.setLabelAngle(Math.PI / 4.0);

        //Sets the Tick Labels means domain value labels by 90 degree
        xAxis.setVerticalTickLabels(true);

        //Try to play with it. It will work only in case of  horizontal tick mark
        xAxis.setTickMarkPosition(DateTickMarkPosition.MIDDLE);

        //set date format
//        xaxis.setDateFormatOverride(new SimpleDateFormat("HH:mm:ss MM-dd-yy"));
        xAxis.setDateFormatOverride(new SimpleDateFormat(DateUtil.SIMPLE_DATE_PATTERN));

        final NumberAxis yAxis = (NumberAxis) plot.getRangeAxis();
        //To set range values integer only. Default are float
        yAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        yAxis.setRange(ChartUtil.RANGE);

        return chart;
    }

    @Override
    public JFreeChart build() {
        ChartInfo info = this.getChartInfo();
        final JFreeChart graph = ChartFactory.createTimeSeriesChart(
                info.getTitle(),
                info.getxAxisLabel(),
                info.getyAxisLabel(),
                this.getDataset(),
                info.isShowLegend(),
                info.isShowToolTips(),
                info.isShowUrls()
        );
        return setDefaults(graph);
    }

}
